2019_reich_clapping_music.py

#

SPDX-FileCopyrightText: 2019 Aleksandar Stoimenov & Pâris Lamboray SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be

SPDX-License-Identifier: GPL-3.0-or-later

import bpy
import random
#

These are the different rythms, values are assigned to the frequency ranges occupied by them

kicks = 3 = bass frequencies spectrum, snares = 2 = medium frequencies spectrum, hats = 1 = high frequency spectrum

ClappingMusic = [2, 2, 2, 0, 2, 2, 0, 2, 0, 2, 2, 0]  # CLAPPING MUSIC

Reggaeton = [3, 0, 0, 2, 3, 0, 2, 0, 3, 0, 0, 2, 3, 0, 2, 0]  # REGGAETON

AmenBreak = [
    3,
    0,
    3,
    0,
    2,
    0,
    1,
    2,
    1,
    2,
    3,
    3,
    2,
    0,
    1,
    2,
    3,
    0,
    3,
    0,
    2,
    0,
    1,
    2,
    1,
    2,
    3,
    0,
    2,
    0,
    1,
    2,
]  # AMEN BREAK

UkGarage = [
    3,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    0,
    0,
    3,
    0,
    2,
    0,
    1,
    0,
    3,
    0,
    3,
    0,
    2,
    0,
    1,
    0,
    2,
    0,
    3,
    0,
    2,
    0,
    1,
    0,
]  # UK GARAGE

Trap = [
    3,
    0,
    1,
    0,
    1,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    1,
    0,
    3,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    1,
    0,
    1,
    0,
]  # TRAP

Samba = [3, 0, 1, 3, 3, 0, 1, 3, 3, 0, 1, 3, 3, 0, 1, 3]  # SAMBA
#

This creates a random rythm

fixedvalue = random.randint(1, 16)

RandomMeasure = []

for i in range(fixedvalue * 2):
    RandomMeasure.append(random.randint(0, 3))
#

This is to choose from one of the different partitions

randomvalue = random.randint(0, 6)

if randomvalue == 0:
    OriginalMeasure = ClappingMusic.copy()
elif randomvalue == 1:
    OriginalMeasure = Reggaeton.copy()
elif randomvalue == 2:
    OriginalMeasure = AmenBreak.copy()
elif randomvalue == 3:
    OriginalMeasure = UkGarage.copy()
elif randomvalue == 4:
    OriginalMeasure = Trap.copy()
elif randomvalue == 5:
    OriginalMeasure = Samba.copy()
else:
    OriginalMeasure = RandomMeasure.copy()
#

Copy of the first measure, this is the second players measure

ChangingMeasure = OriginalMeasure.copy()
#

This list is for rotation values

ListForRotation = []

for i in range(len(OriginalMeasure)):
    ListForRotation.append(0)
#

Shifts the second player measure to the left

#
def left_shift():
    ChangingMeasure.append(ChangingMeasure[0])
    ChangingMeasure.pop(0)
#

This script is for spawning rows of primitives

#

Spawn cubes row and position them vertically in link with the second measure values

#
def cube_spawn():
    for x, y in zip(ChangingMeasure, range(len(ChangingMeasure))):
        bpy.ops.mesh.primitive_cube_add(location=(0, y, x), size=1)
    item = "MESH"
    bpy.ops.object.select_all(action="DESELECT")
    bpy.ops.object.select_by_type(type=item)
    bpy.ops.transform.translate(value=(1, 0.0, 0.0))
#

Spawn cubes, then shift the partition left

#
def cube_spawn_left_shift():
    cube_spawn()
    left_shift()
#

Spawn cylinder rows and position them vertically in link with the first measure values

#
def collones():
    for x, y in zip(OriginalMeasure, range(len(OriginalMeasure))):
        if x > 0:
            bpy.ops.mesh.primitive_cylinder_add(
                location=(0, y, x),
                radius=0.14164971288,
                depth=1,
                rotation=(0, 3.14159 / 2, 0),
            )
#

This codes aims to select each cube individually and then apply transformations to them

#

This is to create a list of cubes, to call them one by one The list goes from Cube.001 to Cube.999

CubeList = ["Cube." + "{0:03}".format(i) for i in range(1000)]
CubeList[0] = "Cube"
#

Here we add Cube.1000 to Cube.9999 to the list

jusquadixmille = ["Cube." + "{0:04}".format(i) for i in range(10000)]

for i in range(1000):
    jusquadixmille.pop(0)

for i in range(9000):
    CubeList.append(jusquadixmille[0])
    jusquadixmille.pop(0)
#

This script is to skip the cube row, it intends to go to the next row for operations

#
def next_measure():
    for i in range(len(OriginalMeasure)):
        CubeList.pop(0)
#

Select a cube, then rotate it through list values

#
def rotating(x, y):
    bpy.ops.object.select_all(action="DESELECT")
    bpy.data.objects[x].select_set(True)
    bpy.ops.transform.rotate(value=3.14159 * y / 180, orient_axis="Z")
    bpy.ops.transform.rotate(value=3.14159 * y / 180, orient_axis="X")
#

Rotate all the cubes

#
def transform_all():
    for x, y in zip(CubeList[0 : len(OriginalMeasure)], ListForRotation):
        rotating(x, y)
    next_measure()
    left_shift()
#

Select a cube, then scale it through list values

#
def scaling(x, y):
    obj = bpy.context.window.scene.objects[x]
    bpy.context.view_layer.objects.active = obj
    bpy.context.active_object.scale.z = y
#

Scale all the cubes

#
def transform_all_scale():
    for x, y in zip(CubeList[0 : len(OriginalMeasure)], ChangingMeasure):
        scaling(x, y)
#

Row spawning and tranformations

#

Spawn cubes and collumns

for i in range(len(OriginalMeasure) + 1):
    collones()
    cube_spawn_left_shift()

for i in range(int(len(OriginalMeasure) / 2 + 1)):
    left_shift()
#

Transform the cubes

ChangingMeasure = OriginalMeasure.copy()

for i in range(len(OriginalMeasure) + 1):
    transform_all_scale()
    transform_all()
    ListForRotation[:] = [i + 90 / (len(OriginalMeasure) / 2) for i in ListForRotation]
#

Here we reset the list to delete flat cubes

CubeList = ["Cube." + "{0:03}".format(i) for i in range(1000)]
CubeList[0] = "Cube"

jusquadixmille = ["Cube." + "{0:04}".format(i) for i in range(10000)]

for i in range(1000):
    jusquadixmille.pop(0)

for i in range(9000):
    CubeList.append(jusquadixmille[0])
    jusquadixmille.pop(0)

ChangingMeasure = OriginalMeasure.copy()
#

This is to delete them

#
def deleting(x, y):
    bpy.ops.object.select_all(action="DESELECT")
    bpy.data.objects[x].select_set(True)
    if y < 1:
        bpy.ops.object.delete()
#
def deleting_all():
    for x, y in zip(CubeList[0 : len(OriginalMeasure)], ChangingMeasure):
        deleting(x, y)
    next_measure()
    left_shift()


for i in range(len(OriginalMeasure) + 1):
    deleting_all()
#

Finally we always put the shape in a 10x10 box

bpy.context.view_layer.objects.active = bpy.context.scene.objects["Cube"]

item = "MESH"
bpy.ops.object.select_all(action="DESELECT")
bpy.ops.object.select_by_type(type=item)
bpy.ops.object.join()

bpy.data.objects["Cube"].dimensions = (10, 10, 10)